package org.gw.ylc.base.interceptor;

import org.gw.ylc.base.context.RequestContext;
import org.gw.ylc.base.context.RequestContextHolder;
import org.gw.ylc.base.context.Roles;
import org.gw.ylc.base.model.UserInfo;
import org.gw.ylc.base.service.AuthenticateService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;

public class LoginInterceptor extends HandlerInterceptorAdapter implements InitializingBean {
	@Autowired
	private AuthenticateService authenticateService;
	@Autowired
	private List<RequestMappingHandlerAdapter> requestMappingHandlerAdapters;

	public void setAuthMode(String authMode) {
	}

	public LoginInterceptor() {
	}

	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HttpSession session = request.getSession(true);
		@SuppressWarnings("unchecked")
		List<UserInfo> users = (List<UserInfo>) session.getAttribute("_users_");
		// 没有登录
		if (CollectionUtils.isEmpty(users)) {
			// 尝试登录
			try {
				users = authenticateService.authenticate(request, "train");
			} catch (Exception e) {
				System.out.println(e.getMessage());
				response.sendRedirect(request.getContextPath() + "/accountError.html");
				return false;
			}
			// 登陆成功
			if (!CollectionUtils.isEmpty(users)) {
				for (UserInfo user : users) {
					user.setPassword(null);
				}
				session.setAttribute("_users_", users);
				session.setAttribute("_current_user_", users.get(0));
			}
		}
		RequestContext context = new RequestContext();
		context.setPageRequest(buildPageRequest(request));
		if (!CollectionUtils.isEmpty(users)) {
			UserInfo currentUser = (UserInfo) session.getAttribute("_current_user_");
			context.setUser(currentUser);
			for (UserInfo user : users) {
				Roles r = Roles.getByOrdinal(user.getType());
				if (r != null) {
					context.getAvailableRoles().add(r);// 可用角色
				}
			}
			RequestContextHolder.set(context);
		} else {
			context.setUser(UserInfo.ANONYMOUS);
			RequestContextHolder.set(context);
		}
		if (handler instanceof HandlerMethod) {
			HandlerMethod m = (HandlerMethod) handler;
			RequestPermission permission = m.getMethodAnnotation(RequestPermission.class);
			if (permission != null) {
				UserInfo user = RequestContextHolder.get().getUser();
				int type = user.getType();
				int[] value = permission.value();
				if (value != null) {
					for (int v : value) {
						if (v == type) {
							return true;
						}
					}
				}
				if (type >= permission.min() && type <= permission.max())
					return true;
				if (type == -1) {
					response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
				} else
					response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
				return false;
			}
		}
		return true;
	}

	private PageRequest buildPageRequest(HttpServletRequest request) {
		String pageNumber = request.getParameter("pageNumber");
		String pageSize = request.getParameter("pageSize");
		int pN = 0;
		int pS = 15;
		if (StringUtils.hasText(pageNumber)) {
			pN = Integer.parseInt(pageNumber);
		}
		if (StringUtils.hasText(pageSize)) {
			pS = Integer.parseInt(pageSize);
		}
		return new PageRequest(pN, pS);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		RequestContextHolder.remove();
		// ContextParamHolder.removeParams();
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		for (RequestMappingHandlerAdapter adapter : requestMappingHandlerAdapters) {
			List<HttpMessageConverter<?>> messageConverters = adapter.getMessageConverters();
			for (HttpMessageConverter<?> c : messageConverters) {
				if (c instanceof StringHttpMessageConverter) {
					StringHttpMessageConverter stringHttpMessageConverter = (StringHttpMessageConverter) c;
					stringHttpMessageConverter.setSupportedMediaTypes(
							Arrays.asList(new MediaType("text", "plain", Charset.forName("utf-8")), MediaType.ALL));
				}
			}

		}
	}

}
